/*---------------------------------------------------------------------------*\
|  DC6809EMUL.C - Motorola 6809 micropocessor emulation                       |
|  Author    : Daniel Coulom - danielcoulom@gmail.com                         |
|  Web sites : http://dcmo5.free.fr - dcto8.free.fr - dcto9p.free.fr          |
|-----------------------------------------------------------------------------|
|                                                                             |
|  This file is part of Thomson emulators by Daniel Coulom.                   |
|                                                                             |
|  These emulators are free software : you can redistribute them and/or       |
|  modify them under the terms of the GNU General Public License as           |
|  published by the Free Software Foundation, either version 3 of the         |
|  License, or (at your option) any later version.                            |
|                                                                             |
|  These emulators are distributed in the hope that they will be useful,      |
|  but WITHOUT ANY WARRANTY; without even the implied warranty of             |
|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU           |
|  General Public License for more details.                                   |
|                                                                             |
|  You should have received a copy of the GNU General Public License          |
|  along with the emulator. If not, see <http://www.gnu.org/licenses/>.       |
|                                                                             |
|-----------------------------------------------------------------------------|
|                     Version septembre 2011                                  |
\*---------------------------------------------------------------------------*/

/* aliases */
#define CC dc6809_cc
#define PC dc6809_pc
#define DP dc6809_dp
#define A  dc6809_a
#define B  dc6809_b
#define X  dc6809_x
#define Y  dc6809_y
#define U  dc6809_u
#define S  dc6809_s
#define N  dc6809_cycles
#define W  dc6809_w

/* 6809 registers */
int dc6809_cc;     /* condition code (EFHINZVC)*/
int dc6809_pc;     /* program counter */
int dc6809_dp;     /* direct pointer */
int dc6809_a;      /* A register */
int dc6809_b;      /* B register */
int dc6809_x;      /* X register */
int dc6809_y;      /* Y register */
int dc6809_u;      /* U register */
int dc6809_s;      /* S register */

/* other global variables */
int dc6809_w;      /* dc6809 work register */
int dc6809_irq;    /* irq trigger  (b0=IRQ, b1=FIRQ, b2=NMI) */
int dc6809_sync;   /* synchronisation flag */
int dc6809_cycles; /* additional cycles */

/* Memory read/write */
extern int  (*Mget1)(int address);
extern void (*Mput1)(int address, int c);
int Mget2 (int x) {x=(Mget1(x)<<8)|Mget1(x+1);return(x);}
int Mgets1(int x) {x=Mget1(x);return(x&0x80)?x-0x100:x;}
int Mgets2(int x) {x=(Mget1(x)<<8)|Mget1(x+1);return(x&0x8000)?x-0x10000:x;}

/*===========================================================================*\
  Processor reset
\*===========================================================================*/
void Reset6809()
{
 dc6809_sync = dc6809_irq = 0;
 dc6809_w = dc6809_cycles = 0;
 DP = A = B = X = Y = U = S = N = W = 0;
 CC = 0x10; PC = (Mget1(0xfffe) << 8) | Mget1(0xffff);
}

/*===========================================================================*\
  Branch functions
\*===========================================================================*/
/*
condition code: CC=EFHINZVC
conditional jump table

C BCC BCS      Z BNE BEQ      V BVC BVS     NZV BGT BLE
0 yes no       0 yes no       0 yes no      000 yes no
1 no  yes      1 no  yes      1 no  yes     100 no  yes
                                            010 no  yes
N BL BMI      ZC BHI BLS     NV BGE BLT     001 no  yes
0 yes no      00 yes no      00 yes no      110 no  yes
1 no  yes     10 no  yes     10 no  yes     101 yes no
              01 no  yes     01 no  yes     011 no  yes
              11 no  no      11 yes no      111 no  yes
*/
/* Short branch */
void Bra() {PC += Mgets1(PC); PC++;}
void Bcc() {if((CC&1)==0)PC+=Mgets1(PC);PC++;}
void Bcs() {if((CC&1)!=0)PC+=Mgets1(PC);PC++;}
void Bvc() {if((CC&2)==0)PC+=Mgets1(PC);PC++;}
void Bvs() {if((CC&2)!=0)PC+=Mgets1(PC);PC++;}
void Bne() {if((CC&4)==0)PC+=Mgets1(PC);PC++;}
void Beq() {if((CC&4)!=0)PC+=Mgets1(PC);PC++;}
void Bhi() {if((CC&5)==0)PC+=Mgets1(PC);PC++;}
void Bls() {if((CC&5)!=0)PC+=Mgets1(PC);PC++;}
void Bpl() {if((CC&8)==0)PC+=Mgets1(PC);PC++;}
void Bmi() {if((CC&8)!=0)PC+=Mgets1(PC);PC++;}
void Bge() {if(((CC&10)==0)||((CC&10)==10))PC+=Mgets1(PC);PC++;}
void Blt() {if(((CC&10)!=0)&&((CC&10)!=10))PC+=Mgets1(PC);PC++;}
void Bgt() {if(((CC&14)==0)||((CC&14)==10))PC+=Mgets1(PC);PC++;}
void Ble() {if(((CC&14)!=0)&&((CC&14)!=10))PC+=Mgets1(PC);PC++;}

/* Long branch */
void LBra() {PC+=Mgets2(PC);N++;PC+=2;}
void LBcc() {if((CC&1)==0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBcs() {if((CC&1)!=0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBvc() {if((CC&2)==0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBvs() {if((CC&2)!=0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBne() {if((CC&4)==0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBeq() {if((CC&4)!=0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBhi() {if((CC&5)==0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBls() {if((CC&5)!=0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBpl() {if((CC&8)==0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBmi() {if((CC&8)!=0){PC+=Mgets2(PC);N++;}PC+=2;}
void LBge() {if(((CC&10)==0)||((CC&10)==10)){PC+=Mgets2(PC);N++;}PC+=2;}
void LBlt() {if(((CC&10)!=0)&&((CC&10)!=10)){PC+=Mgets2(PC);N++;}PC+=2;}
void LBgt() {if(((CC&14)==0)||((CC&14)==10)){PC+=Mgets2(PC);N++;}PC+=2;}
void LBle() {if(((CC&14)!=0)&&((CC&14)!=10)){PC+=Mgets2(PC);N++;}PC+=2;}

/*===========================================================================*\
  One byte operations (CC=EFHINZVC)
\*===========================================================================*/
int Adc(int x, int y) /* verifie */
{
 int r;
 r = x + y + (CC & 1);
 CC &= 0xd0;
 if((x ^ y ^ r) & 0x10) CC |= 32;
 if(r & 0x100) CC |= 1;
 if((x ^ y ^ r ^ (r >> 1)) & 0x80) CC |= 2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Add(int x, int y) /* verifie */
{
 int r;
 r = x + y;
 CC &= 0xd0;
 if((x ^ y ^ r) & 0x10) CC |= 32;
 if(r & 0x100) CC |= 1;
 if((x ^ y ^ r ^ (r >> 1)) & 0x80) CC |= 2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int And(int x, int y) /* verifie */

{
 int r;
 r = x & y;
 CC &= 0xf1;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Asl(int x) /* verifie */
{
 int r;
 r = x << 1;
 CC &= 0xf0;
 if(r & 0x100) CC |= 1;
 if((r ^ x) & 0x80) CC |= 2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Asr(int x) /* verifie */
{
 int r;
 r = (x >> 1) | (x & 0x80);
 CC &= 0xf2;
 CC |= x & 1;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Clr() /* verifie */
{
 CC &= 0xf0;
 CC |= 4;
 return 0;
}

int Com(int x) /* verifie */
{
 int r;
 r = ~x;
 CC &= 0xf0;
 CC |= 1;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

void Daa() /* verifie */
{
 CC &= 0xf3;
 if((CC & 0x20) || ((A & 0x00f) > 0x09)) A += 0x06;
 if((CC & 0x01) || ((A & 0x1f0) > 0x90)) A += 0x60;
 if(A & 0x100) CC |= 1;
 if((A & 0xff) == 0) CC |= 4;
 if((A & 0x80) != 0) CC |= 8;
 A &= 0xff;
}

int Dec(int x) /* verifie */
{
 int r;
 r = x - 1;
 CC &= 0xf1;
 if((r == 0x7f) || (r == 0xff)) CC |= 2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Eor(int x, int y) /* verifie */
{
 int r;
 r = x ^ y;
 CC &= 0xf1;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Inc(int x) /* verifie */
{
 int r;
 r = x + 1;
 CC &= 0xf1;
 if((r == 0x80) || (r == 0x00)) CC |= 2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Ld1(int r) /* verifie */
{
 CC &= 0xf1;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Lsr(int x) /* verifie */
{
 int r;
 r = x >> 1;
 CC &= 0xf2;
 CC |= x & 1;
 if((r & 0xff) == 0) CC |= 4 ;
 return r & 0xff;
}

int Neg(int x) /* verifie */
{
 int r;
 r = -x;
 CC &= 0xf0;
 if(r & 0x100) CC |= 1;
 if(x == 0x80) CC |= 2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Or(int x, int y) /* verifie */
{
 int r;
 r = x | y;
 CC &= 0xf1;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Rol(int x) /* verifie */
{
 int r;
 r = (x << 1) | (CC & 1);
 CC &= 0xf0;
 if(r & 0x100) CC |= 1;
 if((r ^ x) & 0x80) CC |=2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Ror(int x) /* verifie */
{
 int r;
 r = (x >> 1) | ((CC & 1) << 7);
 CC &= 0xf2;
 CC |= x & 1;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

int Sbc(int x, int y) /* verifie */
{
 int r;
 r = x - y - (CC & 1);
 CC &= 0xf0;
 if(r & 0x100) CC |= 1;
 if((x ^ y ^ r ^ (r>>1)) & 0x80) CC |= 2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

void St1(int r, int y) /* verifie */
{
 CC &= 0xf1;
 Mput1(y, r);
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
}

int Sub(int x, int y) /* verifie */
{
 int r = x - y;
 CC &= 0xf0;
 if(r & 0x100) CC |= 1;
 if((x ^ y ^ r ^ (r>>1)) & 0x80) CC |= 2;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
 return r & 0xff;
}

void Tst1(int r) /* verifie */
{
 CC &= 0xf1;
 if((r & 0xff) == 0) CC |= 4;
 if((r & 0x80) != 0) CC |= 8;
}

/*===========================================================================*\
  Two bytes operations (CC=EFHINZVC)
\*===========================================================================*/
void Dload(int x)
{
 A = (x & 0xff00) >> 8;
 B = x & 0xff;
}

void Addd(int x)
{
 int d = (A << 8) | B;
 int r = d + (x & 0xffff);
 CC &= 0xf0;
 if(r & 0x10000) CC |= 1;
 if((d ^ x ^ r ^ (r >> 1)) & 0x8000) CC |=2;
 A = (r & 0xff00) >> 8;
 B = r & 0xff;
 if((r & 0xffff) == 0) CC |= 4;
 if((r & 0x8000) != 0) CC |= 8;
}

void Cmp2(int x, int y)
{
 int r = x - y;
 CC &= 0xf0;
 if(r & 0x10000) CC |= 1;
 if((x ^ y ^ r ^ (r >> 1)) & 0x8000) CC |=2;
 if((r & 0xffff) == 0) CC |= 4;
 if((r & 0x8000) != 0) CC |= 8;
}

void Cmpd(int x)
{
 int d = (A << 8) | B;
 int r = d - x;
 CC &= 0xf0;
 if(r & 0x10000) CC |= 1;
 if((d ^ x ^ r ^ (r >> 1)) & 0x8000) CC |=2;
 if((r & 0xffff) == 0) CC |= 4;
 if((r & 0x8000) != 0) CC |= 8;
}

void Ldd(int r)
{
 A = (r & 0xff00) >> 8;
 B = r & 0xff;
 CC &= 0xf1;
 if((r & 0xffff) == 0) CC |= 4;
 if((r & 0x8000) != 0) CC |= 8;
}

int Ld2(int r)
{
 CC &= 0xf1;
 if((r & 0xffff) == 0) CC |= 4;
 if((r & 0x8000) != 0) CC |= 8;
 return r & 0xffff;
}

void Mul()
{
 int r = A * B;
 A = (r & 0xff00) >> 8;
 B = (r & 0xff);
 CC &= 0xf2;
 if(B & 0x80) CC |= 1;
 if((r & 0xffff) == 0) CC |= 4;
}

void Sex()
{
 A = (B & 0x80) ? 0xff : 0;
 CC &= 0xf1;
 if(A == 0) if(B == 0) CC |= 4;
 if(A & 0x80) CC |= 8;
}

void Std(int x)
{
 Mput1(x, A);
 Mput1(x + 1, B);
 CC &= 0xf1;
 if(A == 0) if(B == 0) CC |= 4;
 if(A & 0x80) CC |= 8;
}

void St2(int r, int y)
{
 Mput1(y, (r & 0xff00) >> 8);
 Mput1(y + 1, r & 0xff);
 CC &= 0xf1;
 if((r & 0xffff) == 0) CC |= 4;
 if((r & 0x8000) != 0) CC |= 8;
}

void Subd(int x)
{
 int d = (A << 8) + B;
 int r = d - x;
 CC &= 0xf0;
 if(r & 0x10000) CC |= 1;
 if((d ^ x ^ r ^ (r >> 1)) & 0x8000) CC |=2;
 A = (r & 0xff00) >> 8;
 B = r & 0xff;
 if((r & 0xffff) == 0) CC |= 4;
 if((r & 0x8000) != 0) CC |= 8;
}

void Tst2(int r) /* verifie */
/*
d'apres Prehisto, LEAX et LEAY positionnent aussi le bit N de CC
mais le 6809 programming manual ne le mentionne pas !!!
*/
{
 CC &= 0xf3;
 if((r & 0xffff) == 0) CC |= 4;
 if((r & 0x8000) != 0) CC |= 8; /* d'apres prehisto */
}

int Addreg(int r, int x)
{
 switch(r & 0x60)
 {
  case 0x00: X += x; X &= 0xffff; return(X);
  case 0x20: Y += x; Y &= 0xffff; return(Y);
  case 0x40: U += x; U &= 0xffff; return(U);
  case 0x60: S += x; S &= 0xffff; return(S);
 }
 return 0;
}

/*===========================================================================*\
  Stack operations (CC=EFHINZVC)
\*===========================================================================*/
void Pshs(int c)
{
 if(c & 0x80) {S--; Mput1(S, PC& 0xff); S--; Mput1(S, (PC& 0xff00) >> 8); N+=2;}
 if(c & 0x40) {S--; Mput1(S, U & 0xff); S--; Mput1(S, (U & 0xff00) >> 8); N+=2;}
 if(c & 0x20) {S--; Mput1(S, Y & 0xff); S--; Mput1(S, (Y & 0xff00) >> 8); N+=2;}
 if(c & 0x10) {S--; Mput1(S, X & 0xff); S--; Mput1(S, (X & 0xff00) >> 8); N+=2;}
 if(c & 0x08) {S--; Mput1(S, DP); N++;}
 if(c & 0x04) {S--; Mput1(S,  B); N++;}
 if(c & 0x02) {S--; Mput1(S,  A); N++;}
 if(c & 0x01) {S--; Mput1(S, CC); N++;}
 S &= 0xffff;
}

void Pshu(int c)
{
 if(c & 0x80) {U--; Mput1(U, PC& 0xff); U--; Mput1(U, (PC& 0xff00) >> 8); N+=2;}
 if(c & 0x40) {U--; Mput1(U, S & 0xff); U--; Mput1(U, (S & 0xff00) >> 8); N+=2;}
 if(c & 0x20) {U--; Mput1(U, Y & 0xff); U--; Mput1(U, (Y & 0xff00) >> 8); N+=2;}
 if(c & 0x10) {U--; Mput1(U, X & 0xff); U--; Mput1(U, (X & 0xff00) >> 8); N+=2;}
 if(c & 0x08) {U--; Mput1(U, DP); N++;}
 if(c & 0x04) {U--; Mput1(U,  B); N++;}
 if(c & 0x02) {U--; Mput1(U,  A); N++;}
 if(c & 0x01) {U--; Mput1(U, CC); N++;}
 U &= 0xffff;
}

void Puls(int c)
{
 if(c & 0x01) {CC = Mget1(S); S++; N++;}
 if(c & 0x02) { A = Mget1(S); S++; N++;}
 if(c & 0x04) { B = Mget1(S); S++; N++;}
 if(c & 0x08) {DP = Mget1(S); S++; N++;}
 if(c & 0x10) { X = Mget1(S) << 8; S++;  X |= Mget1(S); S++; N+=2;}
 if(c & 0x20) { Y = Mget1(S) << 8; S++;  Y |= Mget1(S); S++; N+=2;}
 if(c & 0x40) { U = Mget1(S) << 8; S++;  U |= Mget1(S); S++; N+=2;}
 if(c & 0x80) {PC = Mget1(S) << 8; S++; PC |= Mget1(S); S++; N+=2;}
 S &= 0xffff;
}

void Pulu(int c)
{
 if(c & 0x01) {CC = Mget1(U); U++; N++;}
 if(c & 0x02) { A = Mget1(U); U++; N++;}
 if(c & 0x04) { B = Mget1(U); U++; N++;}
 if(c & 0x08) {DP = Mget1(U); U++; N++;}
 if(c & 0x10) { X = Mget1(U) << 8; U++;  X |= Mget1(U); U++; N+=2;}
 if(c & 0x20) { Y = Mget1(U) << 8; U++;  Y |= Mget1(U); U++; N+=2;}
 if(c & 0x40) { S = Mget1(U) << 8; U++;  S |= Mget1(U); U++; N+=2;}
 if(c & 0x80) {PC = Mget1(U) << 8; U++; PC |= Mget1(U); U++; N+=2;}
 U &= 0xffff;
}

/*===========================================================================*\
  Exchange and transfer operations (CC=EFHINZVC)
\*===========================================================================*/
int Getreg(int n)
{
 int reg;
 switch(n & 0x0f)
 {
  case 0x00: reg = (A << 8) | B; break;
  case 0x01: reg = X; break;
  case 0x02: reg = Y; break;
  case 0x03: reg = U; break;
  case 0x04: reg = S; break;
  case 0x05: reg = PC; break;
  case 0x08: reg = A | 0xff00; break;
  case 0x09: reg = B | 0xff00; break;
  case 0x0a: reg = CC | 0xff00; break;
  case 0x0b: reg = DP | 0xff00; break;
  default:   reg = 0xffff; break;
 }
 return reg;
}

void Setreg(int n, int reg)
{
 switch(n & 0x0f)
 {
  case 0x00: Dload(reg); break;
  case 0x01: X = reg; break;
  case 0x02: Y = reg; break;
  case 0x03: U = reg; break;
  case 0x04: S = reg; break;
  case 0x05: PC = reg; break;
  case 0x08: A = reg & 0xff; break;
  case 0x09: B = reg & 0xff; break;
  case 0x0a: CC = reg & 0xff; break;
  case 0x0b: DP = reg & 0xff; break;
 }
}

void Exg(int c)
{
 W = Getreg(c);
 Setreg(c, Getreg(c >> 4));
 Setreg(c >> 4, W);
}

void Tfr(int c)
{
 Setreg(c, Getreg(c >> 4));
}

/*===========================================================================*\
   Load W with instruction operand
\*===========================================================================*/

void Direct()   {W = (DP << 8) | Mget1(PC); PC++;}

void Extended() {W = (Mget1(PC) <<8 ) | (Mget1(PC + 1)); PC+=2;}

void Indexed()
{
 int i = Mget1(PC);
 PC++;
 switch(i & 0x9f)
 {
  case 0x80: N = 2; W = Addreg(i, 1) - 1; break;                         /* ,R+        */
  case 0x81: N = 3; W = Addreg(i, 2) - 2; break;                         /* ,R++       */
  case 0x82: N = 2; W = Addreg(i, -1); break;                            /* ,-R        */
  case 0x83: N = 3; W = Addreg(i, -2); break;                            /* ,--R       */
  case 0x84: N = 0; W = Addreg(i, 0); break;                             /* ,R         */
  case 0x85: N = 1; W = Addreg(i, 0) + B - ((B&0x80)<<1); break;         /* B,R        */
  case 0x86: N = 1; W = Addreg(i, 0) + A - ((A&0x80)<<1); break;         /* A,R        */
  case 0x87: N = 0; W = Addreg(i, 0); break;                             /* invalid    */
  case 0x88: N = 1; W = Addreg(i, 0) + Mgets1(PC); PC++; break;          /* char,R     */
  case 0x89: N = 4; W = Addreg(i, 0) + Mgets2(PC); PC+=2; break;         /* word,R     */
  case 0x8a: N = 0; W = Addreg(i, 0); break;                             /* invalid    */
  case 0x8b: N = 4; W = Addreg(i, 0) +((A<<8)|B)-((A&0x80)<<9);break;    /* D,R        */
  case 0x8c: N = 1; W = PC + 1 + Mgets1(PC); PC++; break;                /* char,PCR   */
  case 0x8d: N = 5; W = PC + 2 + Mgets2(PC); PC+=2; break;               /* word,PCR   */
  case 0x8e: N = 0; W = Addreg(i, 0); break;                             /* invalid    */
  case 0x8f: N = 0; W = Addreg(i, 0); break;                             /* invalid    */
  case 0x90: N = 3; W = Mget2(Addreg(i, 0)); break;                      /* invalid    */
  case 0x91: N = 6; W = Mget2(Addreg(i, 2) - 2); break;                  /* [,R++]     */
  case 0x92: N = 3; W = Mget2(Addreg(i, 0)); break;                      /* invalid    */
  case 0x93: N = 6; W = Mget2(Addreg(i, -2)); break;                     /* [,--R]     */
  case 0x94: N = 3; W = Mget2(Addreg(i, 0)); break;                      /* [,R]       */
  case 0x95: N = 4; W = Mget2(Addreg(i, 0) + B - ((B&0x80)<<1)); break;  /* [B,R]      */
  case 0x96: N = 4; W = Mget2(Addreg(i, 0) + A - ((A&0x80)<<1)); break;  /* [A,R]      */
  case 0x97: N = 3; W = Mget2(Addreg(i, 0)); break;                      /* invalid    */
  case 0x98: N = 4; W = Mget2(Addreg(i, 0) + Mgets1(PC)); PC++; break;   /* [char,R]   */
  case 0x99: N = 7; W = Mget2(Addreg(i, 0) + Mgets2(PC)); PC+=2; break;  /* [word,R]   */
  case 0x9a: N = 3; W = Mget2(Addreg(i, 0)); break;                      /* invalid    */
  case 0x9b: N = 7; W = Mget2(Addreg(i, 0)+((A<<8)|B)-((A&0x80)<<9)); break; /* [D,R]      */
  case 0x9c: N = 4; W = Mget2(PC+1 +Mgets1(PC)); PC++; break;            /* [char,PCR] */
  case 0x9d: N = 8; W = Mget2(PC+2 +Mgets2(PC)); PC+=2; break;           /* [word,PCR] */
  case 0x9e: N = 3; W = Mget2(Addreg(i, 0)); break;                      /* invalid    */
  case 0x9f: N = 5; W = Mget2(PC); W = Mget2(W); PC+=2; break;           /* [word]     */
  default  : N = 1; W = Addreg(i, 0) + (i&0x1f) - ((i&0x10)<<1); break;  /* 5 bits,R   */
  /* Assumes 0x84 for invalid bytes 0x87 0x8a 0x8e 0x8f */
  /* Assumes 0x94 for invalid bytes 0x90 0x92 0x97 0x9a 0x9e */
 }
 W &= 0xffff;
}

/*===========================================================================*\
   Interrupt requests (CC=EFHINZVC)
\*===========================================================================*/

int Nmi()  /*non masquable interrupt     a verifier !!!! */
{
 dc6809_irq &= 0xfb;        /* raz flag nmi */
 CC |= 0x80;
 Pshs(0xff);
 CC |= 0x40;
 CC |= 0x10;
 PC = Mget2(0xfffc);
 return 1;
}

int Firq() /*fast interrupt request*/
{
 if(CC & 0x40) return 0;    /* si les FIRQs sont masquees */
 dc6809_irq &= 0xfd;        /* raz flag firq */
 CC &= ~0x80;
 Pshs(0x81);
 CC |= 0x40;
 CC |= 0x10;
 PC = Mget2(0xfff6);
 return 1;
}

int Irq() /*interrupt request*/
{
 if(dc6809_sync == 1) dc6809_sync = 2; /* si attente synchro, indicateur d'interruption */
 if(CC & 0x10) return 0;               /* si les IRQs sont masquees */
 dc6809_irq &= 0xfe;                   /* raz flag irq */
 CC |= 0x80;
 Pshs(0xff);
 CC |= 0x10;
 PC = Mget2(0xfff8);
 return 1;
}

void Swi(int n) /*software interrupt*/
{
 CC |= 0x80;
 Pshs(0xff);
 CC |= 0x40;
 CC |= 0x10;
 if(n == 1) {PC = Mget2(0xfffa); return;}
 if(n == 2) {PC = Mget2(0xfff4); return;}
 if(n == 3) {PC = Mget2(0xfff2); return;}
}

void Rti()
{
 Puls(0x01);
 if(CC & 0x80) Puls(0xfe); else Puls(0x80);
}

void Sync()
{
 /* positionner le flag d'attente de synchronisation */
 if(dc6809_sync == 0) dc6809_sync = 1;
 /* boucle si aucune interruption n'a ete detectee */
 if(dc6809_sync != 2) PC--;
 /* si interruption detectee: raz du flag d'attente de synchronisation */
 if(dc6809_sync == 2) dc6809_sync = 0;
}


/*===========================================================================*\
  Execute one operation at pc address and set pc to next opcode address
\*===========================================================================*/
int Run6809()
/*
Return value is set to :
- cycle count for the executed instruction when operation code is legal
- negative value (-code) when operation code is illegal
*/
{
 int code;
 N = 0; /*initialisation du nombre de cycles additionnels*/
 if(dc6809_irq & 4) if(Nmi()) return 7 + N;   /*traitement NMI*/
 if(dc6809_irq & 2) if(Firq()) return 7 + N; /*traitement FIRQ*/
 if(dc6809_irq & 1) if(Irq()) return 7 + N;   /*traitement IRQ*/
 code = 0;
 while(1) /*lecture du code de l'instruction*/
 {
  PC &= 0xffff;
  code += Mget1(PC); PC++;
  if((code & 0xfe) != 0x10) break;
  code = (code & 0xff) << 8;
 }
 switch(code) /*execution de l'instruction*/
 {
  case 0x00: Direct(); Mput1(W, Neg(Mget1(W))); return 6;        /* NEG  /$ */
  case 0x01: Direct(); return 3;                            /*undoc BRN     */
  /*
  case 0x02: if(CC&C1){Mput1(wd, Com(Mget1(W))); return 6;} / undoc COM  /$  /
             else{Mput1(W, Neg(Mget1(W))); return 6;}       / undoc NEG  /$  /
  */
  case 0x03: Direct(); Mput1(W, Com(Mget1(W))); return 6;        /* COM  /$ */
  case 0x04: Direct(); Mput1(W, Lsr(Mget1(W))); return 6;        /* LSR  /$ */
  /*
  case 0x05: Mput1(W, Lsr(Mget1(W))); return 6;             / undoc LSR  /$  /
  */
  case 0x06: Direct(); Mput1(W, Ror(Mget1(W))); return 6;        /* ROR  /$ */
  case 0x07: Direct(); Mput1(W, Asr(Mget1(W))); return 6;        /* ASR  /$ */
  case 0x08: Direct(); Mput1(W, Asl(Mget1(W))); return 6;        /* ASL  /$ */
  case 0x09: Direct(); Mput1(W, Rol(Mget1(W))); return 6;        /* ROL  /$ */
  case 0x0a: Direct(); Mput1(W, Dec(Mget1(W))); return 6;        /* DEC  /$ */
  case 0x0c: Direct(); Mput1(W, Inc(Mget1(W))); return 6;        /* INC  /$ */
  case 0x0d: Direct(); Tst1(Mget1(W)); return 6;                 /* TST  /$ */
  case 0x0e: Direct(); PC = W; return 3;                         /* JMP  /$ */
  case 0x0f: Direct(); Mput1(W, Clr()); return 6;                /* CLR  /$ */

  case 0x12: return 2;                                           /* NOP     */
  case 0x13: Sync(); return 4;                                   /* SYNC    */
  case 0x16: LBra(); return 5;                                   /* LBRA    */
  case 0x17: PC+=2; Pshs(0x80); PC += Mgets2(PC - 2); return 9;  /* LBSR    */
  case 0x19: Daa(); return 2;                                    /* DAA     */
  case 0x1a: CC |= Mget1(PC); PC++; return 3;                    /* ORCC #$ */
  case 0x1c: CC &= Mget1(PC); PC++; return 3;                    /* ANDC #$ */
  case 0x1d: Sex(); return 2;                                    /* SEX     */
  case 0x1e: PC++; Exg(Mget1(PC - 1)); return 8;                 /* EXG     */
  case 0x1f: PC++; Tfr(Mget1(PC - 1)); return 6;                 /* TFR     */

  case 0x20: Bra(); return 3;                                    /* BRA     */
  case 0x21: PC++; return 3;                                     /* BRN     */
  case 0x22: Bhi(); return 3;                                    /* BHI     */
  case 0x23: Bls(); return 3;                                    /* BLS     */
  case 0x24: Bcc(); return 3;                                    /* BCC     */
  case 0x25: Bcs(); return 3;                                    /* BCS     */
  case 0x26: Bne(); return 3;                                    /* BNE     */
  case 0x27: Beq(); return 3;                                    /* BEQ     */
  case 0x28: Bvc(); return 3;                                    /* BVC     */
  case 0x29: Bvs(); return 3;                                    /* BVS     */
  case 0x2a: Bpl(); return 3;                                    /* BPL     */
  case 0x2b: Bmi(); return 3;                                    /* BMI     */
  case 0x2c: Bge(); return 3;                                    /* BGE     */
  case 0x2d: Blt(); return 3;                                    /* BLT     */
  case 0x2e: Bgt(); return 3;                                    /* BGT     */
  case 0x2f: Ble(); return 3;                                    /* BLE     */
  case 0x30: Indexed(); X = W; Tst2(X); return 4 + N;            /* LEAX    */
  case 0x31: Indexed(); Y = W; Tst2(Y); return 4 + N;            /* LEAY    */
  case 0x32: Indexed(); S = W; return 4 + N; /*CC not set*/      /* LEAS    */
  case 0x33: Indexed(); U = W; return 4 + N; /*CC not set*/      /* LEAU    */
  case 0x34: PC++; Pshs(Mget1(PC - 1)); return 5 + N;            /* PSHS    */
  case 0x35: PC++; Puls(Mget1(PC - 1)); return 5 + N;            /* PULS    */
  case 0x36: PC++; Pshu(Mget1(PC - 1)); return 5 + N;            /* PSHU    */
  case 0x37: PC++; Pulu(Mget1(PC - 1)); return 5 + N;            /* PULU    */
  case 0x39: Puls(0x80); return 5;                               /* RTS     */
  case 0x3a: X += B; X &= 0xffff; return 3;                      /* ABX     */
  case 0x3b: Rti(); return 4 + N;                                /* RTI     */
  case 0x3c: CC &= Mget1(PC); PC++; CC |= 0x80; return 20;       /* CWAI    */
  case 0x3d: Mul(); return 11;                                   /* MUL     */
  case 0x3f: Swi(1); return 19;                                  /* SWI     */

  case 0x40: A = Neg(A); return 2;                               /* NEGA    */
  case 0x43: A = Com(A); return 2;                               /* COMA    */
  case 0x44: A = Lsr(A); return 2;                               /* LSRA    */
  case 0x46: A = Ror(A); return 2;                               /* RORA    */
  case 0x47: A = Asr(A); return 2;                               /* ASRA    */
  case 0x48: A = Asl(A); return 2;                               /* ASLA    */
  case 0x49: A = Rol(A); return 2;                               /* ROLA    */
  case 0x4a: A = Dec(A); return 2;                               /* DECA    */
  case 0x4c: A = Inc(A); return 2;                               /* INCA    */
  case 0x4d: Tst1(A); return 2;                                  /* TSTA    */
  case 0x4f: A = Clr(); return 2;                                /* CLRA    */

  case 0x50: B = Neg(B); return 2;                               /* NEGB    */
  case 0x53: B = Com(B); return 2;                               /* COMB    */
  case 0x54: B = Lsr(B); return 2;                               /* LSRB    */
  case 0x56: B = Ror(B); return 2;                               /* RORB    */
  case 0x57: B = Asr(B); return 2;                               /* ASRB    */
  case 0x58: B = Asl(B); return 2;                               /* ASLB    */
  case 0x59: B = Rol(B); return 2;                               /* ROLB    */
  case 0x5a: B = Dec(B); return 2;                               /* DECB    */
  case 0x5c: B = Inc(B); return 2;                               /* INCB    */
  case 0x5d: Tst1(B); return 2;                                  /* TSTB    */
  case 0x5f: B = Clr(); return 2;                                /* CLRB    */

  case 0x60: Indexed(); Mput1(W, Neg(Mget1(W))); return 6 + N;   /* NEG  IX */
  case 0x63: Indexed(); Mput1(W, Com(Mget1(W))); return 6 + N;   /* COM  IX */
  case 0x64: Indexed(); Mput1(W, Lsr(Mget1(W))); return 6 + N;   /* LSR  IX */
  case 0x66: Indexed(); Mput1(W, Ror(Mget1(W))); return 6 + N;   /* ROR  IX */
  case 0x67: Indexed(); Mput1(W, Asr(Mget1(W))); return 6 + N;   /* ASR  IX */
  case 0x68: Indexed(); Mput1(W, Asl(Mget1(W))); return 6 + N;   /* ASL  IX */
  case 0x69: Indexed(); Mput1(W, Rol(Mget1(W))); return 6 + N;   /* ROL  IX */
  case 0x6a: Indexed(); Mput1(W, Dec(Mget1(W))); return 6 + N;   /* DEC  IX */
  case 0x6c: Indexed(); Mput1(W, Inc(Mget1(W))); return 6 + N;   /* INC  IX */
  case 0x6d: Indexed(); Tst1(Mget1(W)); return 6 + N;            /* TST  IX */
  case 0x6e: Indexed(); PC = W; return 3 + N;                    /* JMP  IX */
  case 0x6f: Indexed(); Mput1(W, Clr()); return 6 + N;           /* CLR  IX */

  case 0x70: Extended(); Mput1(W, Neg(Mget1(W))); return 7;      /* NEG  $  */
  case 0x73: Extended(); Mput1(W, Com(Mget1(W))); return 7;      /* COM  $  */
  case 0x74: Extended(); Mput1(W, Lsr(Mget1(W))); return 7;      /* LSR  $  */
  case 0x76: Extended(); Mput1(W, Ror(Mget1(W))); return 7;      /* ROR  $  */
  case 0x77: Extended(); Mput1(W, Asr(Mget1(W))); return 7;      /* ASR  $  */
  case 0x78: Extended(); Mput1(W, Asl(Mget1(W))); return 7;      /* ASL  $  */
  case 0x79: Extended(); Mput1(W, Rol(Mget1(W))); return 7;      /* ROL  $  */
  case 0x7a: Extended(); Mput1(W, Dec(Mget1(W))); return 7;      /* DEC  $  */
  case 0x7c: Extended(); Mput1(W, Inc(Mget1(W))); return 7;      /* INC  $  */
  case 0x7d: Extended(); Tst1(Mget1(W)); return 7;               /* TST  $  */
  case 0x7e: Extended(); PC = W; return 4;                       /* JMP  $  */
  case 0x7f: Extended(); Mput1(W, Clr()); return 7;              /* CLR  $  */

  case 0x80: A = Sub(A, Mget1(PC)); PC++; return 2;              /* SUBA #$ */
  case 0x81: Sub(A, Mget1(PC)); PC++; return 2;                  /* CMPA #$ */
  case 0x82: A = Sbc(A, Mget1(PC)); PC++; return 2;              /* SBCA #$ */
  case 0x83: Subd(Mget2(PC)); PC+=2; return 4;                   /* SUBD #$ */
  case 0x84: A = And(A, Mget1(PC)); PC++; return 2;              /* ANDA #$ */
  case 0x85: And(A, Mget1(PC)); PC++; return 2;                  /* BITA #$ */
  case 0x86: A = Ld1(Mget1(PC)); PC++; return 2;                 /* LDA  #$ */
  case 0x88: A = Eor(A, Mget1(PC)); PC++; return 2;              /* EORA #$ */
  case 0x89: A = Adc(A, Mget1(PC)); PC++; return 2;              /* ADCA #$ */
  case 0x8a: A = Or(A, Mget1(PC)); PC++; return 2;               /* ORA  #$ */
  case 0x8b: A = Add(A, Mget1(PC)); PC++; return 2;              /* ADDA #$ */
  case 0x8c: Cmp2(X, Mget2(PC)); PC+=2; return 4;                /* CMPX #$ */
  case 0x8d: PC++; Pshs(0x80); PC += Mgets1(PC-1); return 7;     /* BSR     */
  case 0x8e: X = Ld2(Mget2(PC)); PC+=2; return 3;                /* LDX  #$ */

  case 0x90: Direct(); A = Sub(A, Mget1(W)); return 4;           /* SUBA /$ */
  case 0x91: Direct(); Sub(A, Mget1(W)); return 4;               /* CMPA /$ */
  case 0x92: Direct(); A = Sbc(A, Mget1(W)); return 4;           /* SBCA /$ */
  case 0x93: Direct(); Subd(Mget2(W));return 6;                  /* SUBD /$ */
  case 0x94: Direct(); A = And(A, Mget1(W)); return 4;           /* ANDA /$ */
  case 0x95: Direct(); And(A, Mget1(W)); return 4;               /* BITA /$ */
  case 0x96: Direct(); A = Ld1(Mget1(W)); return 4;              /* LDA  /$ */
  case 0x97: Direct(); St1(A, W); return 4;                      /* STA  /$ */
  case 0x98: Direct(); A = Eor(A, Mget1(W)); return 4;           /* EORA /$ */
  case 0x99: Direct(); A = Adc(A, Mget1(W)); return 4;           /* ADCA /$ */
  case 0x9a: Direct(); A = Or(A, Mget1(W)); return 4;            /* ORA  /$ */
  case 0x9b: Direct(); A = Add(A, Mget1(W)); return 4;           /* ADDA /$ */
  case 0x9c: Direct(); Cmp2(X, Mget2(W)); return 6;              /* CMPX /$ */
  case 0x9d: Direct(); Pshs(0x80); PC = W; return 7;             /* JSR  /$ */
  case 0x9e: Direct(); X = Ld2(Mget2(W)); return 5;              /* LDX  /$ */
  case 0x9f: Direct(); St2(X, W); return 5;                      /* STX  /$ */

  case 0xa0: Indexed(); A = Sub(A, Mget1(W)); return 4 + N;      /* SUBA IX */
  case 0xa1: Indexed(); Sub(A, Mget1(W)); return 4 + N;          /* CMPA IX */
  case 0xa2: Indexed(); A = Sbc(A, Mget1(W)); return 4 + N;      /* SBCA IX */
  case 0xa3: Indexed(); Subd(Mget2(W)); return 6 + N;            /* SUBD IX */
  case 0xa4: Indexed(); A = And(A, Mget1(W)); return 4 + N;      /* ANDA IX */
  case 0xa5: Indexed(); And(A, Mget1(W)); return 4 + N;          /* BITA IX */
  case 0xa6: Indexed(); A = Ld1(Mget1(W)); return 4 + N;         /* LDA  IX */
  case 0xa7: Indexed(); St1(A, W); return 4 + N;                 /* STA  IX */
  case 0xa8: Indexed(); A = Eor(A, Mget1(W)); return 4 + N;      /* EORA IX */
  case 0xa9: Indexed(); A = Adc(A, Mget1(W)); return 4 + N;      /* ADCA IX */
  case 0xaa: Indexed(); A = Or(A, Mget1(W)); return 4 + N;       /* ORA  IX */
  case 0xab: Indexed(); A = Add(A, Mget1(W)); return 4 + N;      /* ADDA IX */
  case 0xac: Indexed(); Cmp2(X, Mget2(W)); return 4 + N;         /* CMPX IX */
  case 0xad: Indexed(); Pshs(0x80); PC = W; return 5 + N;        /* JSR  IX */
  case 0xae: Indexed(); X = Ld2(Mget2(W)); return 5 + N;         /* LDX  IX */
  case 0xaf: Indexed(); St2(X, W); return 5 + N;                 /* STX  IX */

  case 0xb0: Extended(); A = Sub(A, Mget1(W)); return 5;         /* SUBA $  */
  case 0xb1: Extended(); Sub(A, Mget1(W)); return 5;             /* CMPA $  */
  case 0xb2: Extended(); A = Sbc(A, Mget1(W)); return 5;         /* SBCA $  */
  case 0xb3: Extended(); Subd(Mget2(W)); return 7;               /* SUBD $  */
  case 0xb4: Extended(); A = And(A, Mget1(W)); return 5;         /* ANDA $  */
  case 0xb5: Extended(); And(A, Mget1(W)); return 5;             /* BITA $  */
  case 0xb6: Extended(); A = Ld1(Mget1(W)); return 5;            /* LDA  $  */
  case 0xb7: Extended(); St1(A, W); return 5;                    /* STA  $  */
  case 0xb8: Extended(); A = Eor(A, Mget1(W)); return 5;         /* EORA $  */
  case 0xb9: Extended(); A = Adc(A, Mget1(W)); return 5;         /* ADCA $  */
  case 0xba: Extended(); A = Or(A, Mget1(W)); return 5;          /* ORA  $  */
  case 0xbb: Extended(); A = Add(A, Mget1(W)); return 5;         /* ADDA $  */
  case 0xbc: Extended(); Cmp2(X, Mget2(W)); return 7;            /* CMPX $  */
  case 0xbd: Extended(); Pshs(0x80); PC = W; return 8;           /* JSR  $  */
  case 0xbe: Extended(); X = Ld2(Mget2(W)); return 6;            /* LDX  $  */
  case 0xbf: Extended(); St2(X, W); return 6;                    /* STX  $  */

  case 0xc0: B = Sub(B, Mget1(PC)); PC++; return 2;              /* SUBB #$ */
  case 0xc1: Sub(B, Mget1(PC)); PC++; return 2;                  /* CMPB #$ */
  case 0xc2: B = Sbc(B, Mget1(PC)); PC++; return 2;              /* SBCB #$ */
  case 0xc3: Addd(Mget2(PC)); PC+=2; return 4;                   /* ADDD #$ */
  case 0xc4: B = And(B, Mget1(PC)); PC++; return 2;              /* ANDB #$ */
  case 0xc5: And(B, Mget1(PC)); PC++; return 2;                  /* BITB #$ */
  case 0xc6: B = Ld1(Mget1(PC)); PC++; return 2;                 /* LDB  #$ */
  case 0xc8: B = Eor(B, Mget1(PC)); PC++; return 2;              /* EORB #$ */
  case 0xc9: B = Adc(B, Mget1(PC)); PC++; return 2;              /* ADCB #$ */
  case 0xca: B = Or(B, Mget1(PC)); PC++; return 2;               /* ORB  #$ */
  case 0xcb: B = Add(B, Mget1(PC)); PC++;return 2;               /* ADDB #$ */
  case 0xcc: Ldd(Mget2(PC)); PC+=2; return 3;                    /* LDD  #$ */
  case 0xce: U = Ld2(Mget2(PC)); PC+=2; return 3;                /* LDU  #$ */

  case 0xd0: Direct(); B = Sub(B, Mget1(W)); return 4;           /* SUBB /$ */
  case 0xd1: Direct(); Sub(B, Mget1(W)); return 4;               /* CMPB /$ */
  case 0xd2: Direct(); B = Sbc(B, Mget1(W)); return 4;           /* SBCB /$ */
  case 0xd3: Direct(); Addd(Mget2(W)); return 6;                 /* ADDD /$ */
  case 0xd4: Direct(); B = And(B, Mget1(W)); return 4;           /* ANDB /$ */
  case 0xd5: Direct(); And(B, Mget1(W)); return 4;               /* BITB /$ */
  case 0xd6: Direct(); B = Ld1(Mget1(W)); return 4;              /* LDB  /$ */
  case 0xd7: Direct(); St1(B, W); return 4;                      /* STB  /$ */
  case 0xd8: Direct(); B = Eor(B, Mget1(W)); return 4;           /* EORB /$ */
  case 0xd9: Direct(); B = Adc(B, Mget1(W)); return 4;           /* ADCB /$ */
  case 0xda: Direct(); B = Or(B, Mget1(W)); return 4;            /* ORB  /$ */
  case 0xdb: Direct(); B = Add(B, Mget1(W)); return 4;           /* ADDB /$ */
  case 0xdc: Direct(); Ldd(Mget2(W)); return 5;                  /* LDD  /$ */
  case 0xdd: Direct(); Std(W); return 5;                         /* STD  /$ */
  case 0xde: Direct(); U = Ld2(Mget2(W)); return 5;              /* LDU  /$ */
  case 0xdf: Direct(); St2(U, W); return 5;                      /* STU  /$ */

  case 0xe0: Indexed(); B = Sub(B, Mget1(W)); return 4 + N;      /* SUBB IX */
  case 0xe1: Indexed(); Sub(B, Mget1(W)); return 4 + N;          /* CMPB IX */
  case 0xe2: Indexed(); B = Sbc(B, Mget1(W)); return 4 + N;      /* SBCB IX */
  case 0xe3: Indexed(); Addd(Mget2(W)); return 6 + N;            /* ADDD IX */
  case 0xe4: Indexed(); B = And(B, Mget1(W)); return 4 + N;      /* ANDB IX */
  case 0xe5: Indexed(); And(B, Mget1(W)); return 4 + N;          /* BITB IX */
  case 0xe6: Indexed(); B = Ld1(Mget1(W)); return 4 + N;         /* LDB  IX */
  case 0xe7: Indexed(); St1(B, W); return 4 + N;                 /* STB  IX */
  case 0xe8: Indexed(); B = Eor(B, Mget1(W)); return 4 + N;      /* EORB IX */
  case 0xe9: Indexed(); B = Adc(B, Mget1(W)); return 4 + N;      /* ADCB IX */
  case 0xea: Indexed(); B = Or(B, Mget1(W)); return 4 + N;       /* ORB  IX */
  case 0xeb: Indexed(); B = Add(B, Mget1(W)); return 4 + N;      /* ADDB IX */
  case 0xec: Indexed(); Ldd(Mget2(W)); return 5 + N;             /* LDD  IX */
  case 0xed: Indexed(); Std(W); return 5 + N;                    /* STD  IX */
  case 0xee: Indexed(); U = Ld2(Mget2(W)); return 5 + N;         /* LDU  IX */
  case 0xef: Indexed(); St2(U, W); return 5 + N;                 /* STU  IX */

  case 0xf0: Extended(); B = Sub(B, Mget1(W)); return 5;         /* SUBB $  */
  case 0xf1: Extended(); Sub(B, Mget1(W)); return 5;             /* CMPB $  */
  case 0xf2: Extended(); B = Sbc(B, Mget1(W)); return 5;         /* SBCB $  */
  case 0xf3: Extended(); Addd(Mget2(W)); return 7;               /* ADDD $  */
  case 0xf4: Extended(); B = And(B, Mget1(W)); return 5;         /* ANDB $  */
  case 0xf5: Extended(); And(B, Mget1(W)); return 5;             /* BITB $  */
  case 0xf6: Extended(); B = Ld1(Mget1(W)); return 5;            /* LDB  $  */
  case 0xf7: Extended(); St1(B, W); return 5;                    /* STB  $  */
  case 0xf8: Extended(); B = Eor(B, Mget1(W)); return 5;         /* EORB $  */
  case 0xf9: Extended(); B = Adc(B, Mget1(W)); return 5;         /* ADCB $  */
  case 0xfa: Extended(); B = Or(B, Mget1(W)); return 5;          /* ORB  $  */
  case 0xfb: Extended(); B = Add(B, Mget1(W)); return 5;         /* ADDB $  */
  case 0xfc: Extended(); Ldd(Mget2(W)); return 6;                /* LDD  $  */
  case 0xfd: Extended(); Std(W); return 6;                       /* STD  $  */
  case 0xfe: Extended(); U = Ld2(Mget2(W)); return 6;            /* LDU  $  */
  case 0xff: Extended(); St2(U, W); return 6;                    /* STU  $  */

  case 0x1021: PC += 2; return 5;                                /* LBRN    */
  case 0x1022: LBhi(); return 5 + N;                             /* LBHI    */
  case 0x1023: LBls(); return 5 + N;                             /* LBLS    */
  case 0x1024: LBcc(); return 5 + N;                             /* LBCC    */
  case 0x1025: LBcs(); return 5 + N;                             /* LBCS    */
  case 0x1026: LBne(); return 5 + N;                             /* LBNE    */
  case 0x1027: LBeq(); return 5 + N;                             /* LBEQ    */
  case 0x1028: LBvc(); return 5 + N;                             /* LBVC    */
  case 0x1029: LBvs(); return 5 + N;                             /* LBVS    */
  case 0x102a: LBpl(); return 5 + N;                             /* LBPL    */
  case 0x102b: LBmi(); return 5 + N;                             /* LBMI    */
  case 0x102c: LBge(); return 5 + N;                             /* LBGE    */
  case 0x102d: LBlt(); return 5 + N;                             /* LBLT    */
  case 0x102e: LBgt(); return 5 + N;                             /* LBGT    */
  case 0x102f: LBle(); return 5 + N;                             /* LBLE    */
  case 0x103f: Swi(2); return 20;                                /* SWI2    */

  case 0x1083: Cmpd(Mget2(PC)); PC+=2; return 5;                 /* CMPD #$ */
  case 0x108c: Cmp2(Y, Mget2(PC)); PC+=2; return 5;              /* CMPY #$ */
  case 0x108e: Y = Ld2(Mget2(PC)); PC+=2; return 4;              /* LDY  #$ */
  case 0x1093: Direct(); Cmpd(Mget2(W)); return 7;               /* CMPD /$ */
  case 0x109c: Direct(); Cmp2(Y, Mget2(W)); return 7;            /* CMPY /$ */
  case 0x109e: Direct(); Y = Ld2(Mget2(W)); return 6;            /* LDY  /$ */
  case 0x109f: Direct(); St2(Y, W); return 6;                    /* STY  /$ */
  case 0x10a3: Indexed(); Cmpd(Mget2(W)); return 7 + N;          /* CMPD IX */
  case 0x10ac: Indexed(); Cmp2(Y, Mget2(W)); return 7 + N;       /* CMPY IX */
  case 0x10ae: Indexed(); Y = Ld2(Mget2(W)); return 6 + N;       /* LDY  IX */
  case 0x10af: Indexed(); St2(Y, W); return 6 + N;               /* STY  IX */
  case 0x10b3: Extended(); Cmpd(Mget2(W)); return 8;             /* CMPD $  */
  case 0x10bc: Extended(); Cmp2(Y, Mget2(W)); return 8;          /* CMPY $  */
  case 0x10be: Extended(); Y = Ld2(Mget2(W)); return 7;          /* LDY  $  */
  case 0x10bf: Extended(); St2(Y, W); return 7;                  /* STY  $  */
  case 0x10ce: S = Ld2(Mget2(PC)); PC+=2; return 4;              /* LDS  #$ */
  case 0x10de: Direct(); S = Ld2(Mget2(W)); return 6;            /* LDS  /$ */
  case 0x10df: Direct(); St2(S, W); return 6;                    /* STS  /$ */
  case 0x10ee: Indexed(); S = Ld2(Mget2(W)); return 6 + N;       /* LDS  IX */
  case 0x10ef: Indexed(); St2(S, W); return 6 + N;               /* STS  IX */
  case 0x10fe: Extended(); S = Ld2(Mget2(W)); return 7;          /* LDS  $  */
  case 0x10ff: Extended(); St2(S, W); return 7;                  /* STS  $  */

  case 0x113f: Swi(3); return 20;                                /* SWI3    */
  case 0x1183: Cmp2(U, Mget2(PC)); PC+=2; return 5;              /* CMPU #$ */
  case 0x118c: Cmp2(S, Mget2(PC)); PC+=2; return 5;              /* CMPS #$ */
  case 0x1193: Direct(); Cmp2(U, Mget2(W)); return 7;            /* CMPU /$ */
  case 0x119c: Direct(); Cmp2(S, Mget2(W)); return 7;            /* CMPS /$ */
  case 0x11a3: Indexed(); Cmp2(U, Mget2(W)); return 7 + N;       /* CMPU IX */
  case 0x11ac: Indexed(); Cmp2(S, Mget2(W)); return 7 + N;       /* CMPS IX */
  case 0x11b3: Extended(); Cmp2(U, Mget2(W)); return 8;          /* CMPU $  */
  case 0x11bc: Extended(); Cmp2(S, Mget2(W)); return 8;          /* CMPS $  */

  default: return -code;                                         /* Illegal */
 }
}
